<script setup>
import { ref, onMounted } from 'vue'
import { useChatStore } from '@/stores/chat'
import { toBase64, getWebSocketUrl } from './util'

const chatStore = useChatStore()

// 状态变量
const isRecording = ref(false)
const isLoading = ref(false)
const recognitionResult = ref('')
const recognitionResultTemp = ref('')
let iatWS = null
let recorder = null

onMounted(() => {
  
  // 初始化 recorder
  recorder = new window.RecorderManager('/recorder')
  
  // 设置录音帧回调
  recorder.onFrameRecorded = ({ isLastFrame, frameBuffer }) => {
    if (iatWS?.readyState === WebSocket.OPEN) {
      iatWS.send(JSON.stringify({
        data: {
          status: isLastFrame ? 2 : 1,
          format: "audio/L16;rate=16000",
          encoding: "raw",
          audio: toBase64(frameBuffer)
        }
      }))
    }
  }
})



const emits = defineEmits(['showText', 'end'])
// 处理识别结果
function handleRecognitionResult(resultData) {
  const jsonData = JSON.parse(resultData)
  if (jsonData.data && jsonData.data.result) {
    const data = jsonData.data.result
    let str = ""
    const ws = data.ws
    for (let i = 0; i < ws.length; i++) {
      str = str + ws[i].cw[0].w
    }
    
    if (data.pgs) {
      if (data.pgs === "apd") {
        recognitionResult.value = recognitionResultTemp.value
        emits('showText', recognitionResult.value)
      }
      recognitionResultTemp.value = recognitionResult.value + str
    } else {
      recognitionResult.value = recognitionResult.value + str
      emits('showText', recognitionResult.value)
    }
  }
  
  if (jsonData.code === 0 && jsonData.data.status === 2) {
    iatWS.close()
  }
  if (jsonData.code !== 0) {
    iatWS.close()
    console.error(jsonData)
  }
}

let delayFunc;
// 开始录音
function startRecording() {
  // 延迟0.5秒后显示录音状态
  delayFunc = setTimeout(() => {
    isLoading.value = false
    isRecording.value = true
  }, 500)
  isLoading.value = true
  const websocketUrl = getWebSocketUrl()
  if (!("WebSocket" in window)) {
    alert("浏览器不支持WebSocket")
    return
  }

  iatWS = new WebSocket(websocketUrl)
  
  iatWS.onopen = () => {
    recorder.start({
      sampleRate: 16000,
      frameSize: 1280
    })

    iatWS.send(JSON.stringify({
      common: {
        app_id: 'f31bcad0'
      },
      business: {
        language: "zh_cn",
        domain: "iat",
        accent: "mandarin",
        vad_eos: 5000,
        dwa: "wpgs"
      },
      data: {
        status: 0,
        format: "audio/L16;rate=16000",
        encoding: "raw"
      }
    }))
  }

  iatWS.onmessage = (e) => {
    handleRecognitionResult(e.data)
  }

  iatWS.onerror = (e) => {
    console.error('WebSocket错误:', e)
    stopRecording()
  }

  iatWS.onclose = () => {
    stopRecording()
  }
}


// 停止录音
function stopRecording() {
  delayFunc && clearTimeout(delayFunc)
  isLoading.value = false
  isRecording.value = false
  recorder?.stop()
  
  // 延迟0.5秒后关闭WebSocket，确保接收完整的识别结果
  setTimeout(() => {
    recorder?.stop()
    iatWS?.close()
    if (recognitionResult.value) {
      emits('end', recognitionResult.value)
    }
    clearResult()
    isLoading.value = false
    isRecording.value = false
  }, 500)
  
}

// 清空结果
function clearResult() {
  recognitionResult.value = ''
  recognitionResultTemp.value = ''
}
</script>

<template>
  <div class="voice-input">
    <div 
      :class="['record-btn', { 'recording': isRecording, 'loading': isLoading }]"
      @mousedown="startRecording()"
      @mouseup="stopRecording()"
    >
      {{ isLoading ? '按住此处说话' : (isRecording ? '' : '按住此处说话') }}
      <img v-if="isRecording && chatStore.showType === 'box'" src="../../../assets/images/box-voice.gif">
      <img v-if="isRecording && chatStore.showType === 'phone'" src="../../../assets/images/phone-voice.gif">
      <img v-if="isRecording && chatStore.showType === 'home'" src="../../../assets/images/home-voice.gif">
      <img v-if="isRecording && chatStore.showType === 'ac'" src="../../../assets/images/ac-voice.gif">
    </div>
  </div>
</template>

<style scoped>
.voice-input {
  height: 40px;
  .record-btn{
    border-radius: 44px;
    line-height: 40px;
    height: 40px;
    text-align: center;
    cursor: pointer;
    transition: all 0.3s ease;
    background-color: #fff;
    user-select: none;
    box-shadow: 0 0 0 1px var(--el-input-border-color, var(--el-border-color)) inset;
    color: #606266;
    background-image: url('../../assets/images/box-voice.gif');
  }

  .record-btn.loading {
    color: #a8abb2;
  }

  .record-btn {
    user-select: none;
    letter-spacing: 2px;
    img{
      height: 40px;
      width: 100%;
      border-radius: 40px;
    }
  }
}


</style>
